<template>
	<uni-popup ref="popup" :safe-area="false" type="bottom" :style="`z-index: ${props.zIndex};`">
		<view class="popup-all">
			<!--
			<viue class="popup-title d-flex d-r a-center j-center">
				<view class="title-text">选择日期</view>
				<image @tap="close" class="title-icon" src="@/static/image/close.png"></image>
			</viue>
			-->
			<view class="date-top d-flex d-r a-center j-between">
				<view @tap="lastMonth" class="icon-btn">
					<image class="date-top-icon" src="@/static/image/date-back.png"></image>
				</view>
				
				<view class="date-top-text">{{showYear}}年{{showMonth+1}}月</view>
				<view @tap="nextMonth" class="icon-btn">
					<image class="date-top-icon" src="@/static/image/date-next.png"></image>
				</view>
				
			</view>
			<view class="date-week d-flex d-r j-between">
				<view class="date-week-cell">
                    <text class="text">日</text>
                </view>
				<view class="date-week-cell">
                    <text class="text">一</text>
                </view>
				<view class="date-week-cell">
                    <text class="text">二</text>
                </view>
				<view class="date-week-cell">
                    <text class="text">三</text>
                </view>
				<view class="date-week-cell">
                    <text class="text">四</text>
                </view>
				<view class="date-week-cell">
                    <text class="text">五</text>
                </view>
				<view class="date-week-cell">
                    <text class="text">六</text>
                </view>
			</view>
			<view class="date-swiper">
				<swiper class="swiper" style="height: 480rpx;" circular :current="current" @change="changeSwiper">
					<swiper-item>
						<view class="date-day d-flex d-r j-between">
							<template v-for="(item,index) in daysList0">
								<view @tap="onClickDate(item)" class="date-day-cell" :style="{ background: isSameDay(item) ? props.color : '#ffffff' }">
						            <text class="text" :style="{ fontWeight: isCurrentDate(item)?600:500 , color: isSameMonthAndYear(item) ? isSameDay(item)? '#ffffff' : isCurrentDate(item)? props.color: '#333333' :'#cccccc' }">{{getDay(item)}}</text>
									<view v-if="isMark(item)" :style="`background: ${props.color};`" class="day-cell-mark"></view>
								</view>
								<view v-if="(index+1)%7==0" class="child-wrap"></view>
							</template>
						</view>
					</swiper-item>
					<swiper-item>
						<view class="date-day d-flex d-r j-between">
							<template v-for="(item,index) in daysList1">
								<view @tap="onClickDate(item)" class="date-day-cell" :style="{ background: isSameDay(item) ? props.color : '#ffffff' }">
						            <text class="text" :style="{ color: isSameMonthAndYear(item) ? isSameDay(item)? '#ffffff' : isCurrentDate(item)? props.color: '#333333' :'#cccccc' }">{{getDay(item)}}</text>
									<view v-if="isMark(item)" :style="`background: ${props.color};`" class="day-cell-mark"></view>
								</view>
								<view v-if="(index+1)%7==0" class="child-wrap"></view>
							</template>
						</view>
					</swiper-item>
					<swiper-item>
						<view class="date-day d-flex d-r j-between">
							<template v-for="(item,index) in daysList2">
								<view @tap="onClickDate(item)" class="date-day-cell" :style="{ background: isSameDay(item) ? props.color : '#ffffff' }">
						            <text class="text" :style="{ color: isSameMonthAndYear(item) ? isSameDay(item)? '#ffffff' : isCurrentDate(item)? props.color: '#333333' :'#cccccc' }">{{getDay(item)}}</text>
									<view v-if="isMark(item)" :style="`background: ${props.color};`" class="day-cell-mark"></view>
								</view>
								<view v-if="(index+1)%7==0" class="child-wrap"></view>
							</template>
						</view>
					</swiper-item>
				</swiper>
			</view>
			<view class="confirm-button d-flex d-r j-center">
				<tm-button _style="border-radius:20rpx;margin: 0 auto;font-weight: 600;" :width="690" :height="80" :shadow="-1"
				    :linear-color="[`${props.color}`, `${props.color}`]" linear="left" :fontSize="32" fontColor="#ffffff" @tap="determine" 
				    label="确认"></tm-button>
			</view>
		</view>
	</uni-popup>
</template>

<script setup lang="tsx" name="dateTable">
import { ref,withDefaults,defineProps } from 'vue';
import moment from 'moment';

interface Props {
	initialDate?:Date,
	color?:string,
	minDate?:string,
	maxDate?:string,
	zIndex?:number,
	markDate?: string[]
}
const props = withDefaults(defineProps<Props>(), {
	initialDate: () => new Date(),//初始日期
	color: "#1DC691",//主题颜色
	minDate:"",//最小可选日期
	maxDate:"",//最大可选日期
	zIndex:100,//显示的层级
	markDate: () => []//高亮显示日期
})
//onGetDate：确认选择函数（传入选择的日期），changeMoon：月份变更触发函数（传入变更后日期）
const emit = defineEmits(["onGetDate","changeMoon"])

const popup = ref()
const showYear = ref(1900);//控件当显示年
const showMonth = ref(0);//控件当前显示月
const selectDate:any = ref();//选中日期

//打开日期弹出框
const open = () => {
	popup.value.open();
	selectDate.value = props.initialDate;//初始化日期为默认选择日期
	showYear.value = moment(props.initialDate).year();
	showMonth.value = moment(props.initialDate).month(); 
	current.value=0;
	daysList0.value = null;
	loadDateShow();
}
//判断是否为标识日期
const isMark = (date:any) => {
	let markDate:any = props.markDate;
	//console.log(props.markDate)
	//let markDate = initialParam.value.markDate;
	if(markDate!=null&&markDate.length>0){
		for(let i=0;i<markDate.length;i++){
			if(isDate(date,moment(markDate[i],"YYYY-MM-DD")))return true;
		}
	}
	return false
}
//点击上一月
const lastMonth = () =>{
	getFindMonth(-1);
	switch(current.value){
		case 0:
			current.value = 2
			break;
		case 1:
			current.value = 0
			break;
		case 2:
			current.value = 1
			break;
	}
}
//点击下一月
const nextMonth = () =>{
	getFindMonth(+1);
	switch(current.value){
		case 0:
			current.value = 1
			break;
		case 1:
			current.value = 2
			break;
		case 2:
			current.value = 0
			break;
	}
}
//计算当前显示的月份个月份
const getFindMonth = (count:number) => {
	loadDateShow();//重新加载控件显示内容
    // 创建一个Date对象，设置为指定的年份和月份  
    // 注意：在JavaScript中，月份是从0开始的，所以我们需要将输入的月份减1  
    let date = new Date(showYear.value, showMonth.value + count);  
    // 获取上一月的年份和月份  
    showYear.value =  date.getFullYear();  
    showMonth.value = date.getMonth(); // 由于月份是从0开始的，我们需要加1以获取常规的月份 
	emit("changeMoon", date);
}  

const isSameDay = (data:any)=>{
    let selectedTime  = moment(selectDate.value);
	let year =  selectedTime.year();
	let month =  selectedTime.month();
	let day =  selectedTime.date();

    let itemTime  = moment(data);
	let itemYear =  itemTime.year();
	let itemMonth =  itemTime.month();
	let itemDay =  itemTime.date();
    if(`${year}${month}${day}`===`${itemYear}${itemMonth}${itemDay}`){
        return true;
    }
    return false;

}

//加载时间显示
const loadDateShow = () => {
	if(current.value===0){
		let date1 = new Date(showYear.value, showMonth.value + 1); 
		let date2 = new Date(showYear.value, showMonth.value - 1);
		daysList1.value = generateDatesForMonth(date1.getFullYear(),date1.getMonth());
		daysList2.value = generateDatesForMonth(date2.getFullYear(),date2.getMonth());
	}
	if(current.value===1){
		let date0 = new Date(showYear.value, showMonth.value - 1); 
		let date2 = new Date(showYear.value, showMonth.value + 1);
		daysList0.value = generateDatesForMonth(date0.getFullYear(),date0.getMonth());
		daysList2.value = generateDatesForMonth(date2.getFullYear(),date2.getMonth());
	}
	if(current.value===2){
		let date0 = new Date(showYear.value, showMonth.value + 1); 
		let date1 = new Date(showYear.value, showMonth.value - 1);
		daysList0.value = generateDatesForMonth(date0.getFullYear(),date0.getMonth());
		daysList1.value = generateDatesForMonth(date1.getFullYear(),date1.getMonth());
	}
	//初始化
	if(daysList0.value==null){
		daysList0.value = generateDatesForMonth(showYear.value,showMonth.value);
	}
}
//点击选择时间
const onClickDate = (date:any) => {
	if(!isSameMonthAndYear(date)){
		let showDate = new Date(showYear.value,showMonth.value);
		if(showDate>date){
			lastMonth();
		}else{
			nextMonth()
		}
	}else{
		//判断时间是否超过限制范围
		if(moment(moment(date).format("YYYY-MM-DD")).isBefore(moment(props.minDate,"YYYY-MM-DD"))){
			uni.showToast({
			    icon: "none",
			    title: '最小可选日期为' + props.minDate,
			    duration: 1500,
			});
			return;
		}
		if(moment(moment(date).format("YYYY-MM-DD")).isAfter(moment(props.maxDate,"YYYY-MM-DD"))){
			uni.showToast({
				icon: "none",
				title: '时间还没到哦',
				//title: '最大可选日期为' + props.maxDate,
				duration: 1500,
			});
			return;
		}
	}
	selectDate.value = date;
}

//根据日期判断date是否为当前控件显示月
const isSameMonthAndYear = (date:any) => {
	let dasts  = moment(date);
	let year =  dasts.year();
	let month =  dasts.month();
	return year===showYear.value&&month===showMonth.value
}
//判断是否为当前日期
const isCurrentDate = (date:any) =>{
	return moment(date).format('YYYY-MM-DD') === moment().format('YYYY-MM-DD')
}
//判断两dated对象是否相等
const isDate = (date1:any,date2:any) => {
	return moment(date1).format('YYYY-MM-DD') === moment(date2).format('YYYY-MM-DD')
}
//根据date对象获取“日”
const getDay = (date:any) => {
	const momentObj = moment(date);  
	// 获取日  
	const day = momentObj.date();  
	return day;
}
const generateDatesForMonth = (year:number, month:number) => {  
  const firstDayOfMonth = new Date(year, month, 1);  
  const lastDayOfMonth = new Date(year, month + 1, 0);  
  
  const daysInPreviousMonth = new Date(year, month, 0).getDate();  
  
  let dates = [];  
  
  // 补充上个月最后几天  
  const startDayOfWeek = firstDayOfMonth.getDay();  
  if (startDayOfWeek !== 0) {  
    for (let i = daysInPreviousMonth - startDayOfWeek + 1; i <= daysInPreviousMonth; i++) {  
      dates.push(new Date(year, month - 1, i));  
    }  
  }  
  // 生成本月所有日期  
  for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {  
    dates.push(new Date(year, month, i));  
  }  
  // 补充下个月初几天  
  const endDayOfWeek = lastDayOfMonth.getDay();
  if (endDayOfWeek !== 6) {  
    for (let i = 1; i <= 6 - endDayOfWeek; i++) {  
      dates.push(new Date(year, month + 1, i));  
    }  
  }  
  return dates;  
}
//关闭日期弹出框
const close = () => {
	popup.value.close();
}

const determine = () => {
	if(moment(moment(selectDate.value).format("YYYY-MM-DD")).isBefore(moment(props.minDate,"YYYY-MM-DD"))){
		uni.showToast({
		    icon: "none",
		    title: '最小可选日期为' + props.minDate,
		    duration: 1500,
		});
		return;
	}
	if(moment(moment(selectDate.value).format("YYYY-MM-DD")).isAfter(moment(props.maxDate,"YYYY-MM-DD"))){
		uni.showToast({
			icon: "none",
			title: '最大可选日期为' + props.maxDate,
			duration: 1500,
		});
		return;
	}
	close();//关闭
	emit("onGetDate", selectDate.value);
}

const current = ref(0);
const changeSwiper = (event:any) => {
	if((current.value==0&&event.detail.current==1)||(current.value==1&&event.detail.current==2)||(current.value==2&&event.detail.current==0)){
		getFindMonth(+1)
	}
	if((current.value==0&&event.detail.current==2)||(current.value==1&&event.detail.current==0)||(current.value==2&&event.detail.current==1)){
		getFindMonth(-1)
	}
	current.value = event.detail.current;
}
//根据当前显示时间与swiper的current计算当前日期
const daysList0:any = ref();
const daysList1:any = ref();
const daysList2:any = ref();


defineExpose({
  open,
  close
});
</script>

<style lang="scss" scoped>
.a-center {
    align-items: center;
}

.j-center {
    justify-content: center;
}

.j-between {
    justify-content: space-between;
}
.j-end {
    justify-content: flex-end;
}

.j-around {
    justify-content: space-around;
}

.d-flex{
    display: flex;
}

.d-c {
    flex-direction: column;
}
.d-r {
    flex-direction: row;
}

.j-end {
    justify-content: flex-end;
}
.popup-all{
	width: 750rpx;
	background: #FFFFFF;
	border-radius: 20rpx 20rpx 0rpx 0rpx;
	.popup-title{
		position: relative;
		height: 100rpx;
		border-radius: 20rpx 20rpx 0rpx 0rpx;
		.title-text{
			font-size: 32rpx;
			font-family: PingFangSC-Regular, PingFang SC;
			font-weight: 400;
			color: #333333;
		}
		.title-icon{
			position:absolute;
			top:32rpx;
			right: 30rpx;
			width: 36rpx;
			height: 36rpx;
		}
	}
	.date-top{
		/*padding:0 50rpx;*/
		height: 116rpx;
		.icon-btn{
			padding:0 50rpx;
			.date-top-icon{
				width: 20rpx;
				height: 20rpx;
			}
		}
		.date-top-text{
			font-size: 30rpx;
			font-family: PingFangSC-Regular, PingFang SC;
			font-weight: 400;
			color: #333333;
		}
	}
	.date-week{
		padding:23rpx 40rpx 5rpx 40rpx;
		.date-week-cell{
            display:flex;
            flex-direction: row;
            align-items:center;
            justify-content: center;
			width: 50rpx;
			height: 50rpx;
			font-size: 28rpx;
			font-family: PingFangSC-Regular, PingFang SC;
			font-weight: 400;
			color: #999999;
		}
	}
	.date-swiper{
		width: 750rpx;
		.date-day{
			flex-wrap: wrap;
			padding:23rpx 40rpx 34rpx 40rpx;
			.date-day-cell{
				position: relative;
		        display:flex;
		        flex-direction: row;
		        align-items:center;
		        justify-content: center;
				width: 50rpx;
				height: 50rpx;
				border-radius: 25rpx;
		        background:#fff;
		        &.selected{
		                background:#1DC691;
		            }
		        .text{
		            font-size: 28rpx;
		            color: #333333;
		            &.notSameMonth{
		                color:#ccc;
		            }
		            &.selected{
		                color:#fff;
		            }
		        }
				
				.day-cell-mark{
					position:absolute;
					top:1rpx;
					right: 1rpx;
					width: 10rpx;
					height: 10rpx;
					border: 1rpx solid #FFFFFF;
					border-radius: 5rpx;
				}
			}
			.child-wrap{  
		      width: 690rpx;
			  height: 21rpx;
			}
		}
	}
}
.confirm-button{
	padding-bottom: 60rpx;
}
</style>